#include "../include/analysisCommand.h"
#include <stdio.h>
#include <sys/sendfile.h>
#include <sys/mman.h>
typedef struct train_s{
    int type;
    int length;
    char data[1000];
}train_t;

int recvn(int sockfd,void *buf,int length){
    int total=0;
    char * p=(char *)buf;
    while(total<length){
        int ret=recv(sockfd,p+total,length-total,0);
        total+=ret;
    }
    return 0;
}

/* int transfile(int netfd){ */
int s_download(int netfd,commandStack_t *pcommandStack){
    char path[1024]={0};
    assemble_stack(pcommandStack,path);
    train_t train;

    recvn(netfd,&train.type,sizeof(train.type));
    if(train.type==11){
        // 执行断点续传逻辑
        // 收文件名
        char filename[1024]={0};
        recvn(netfd,&train.type,sizeof(train.type));
        recvn(netfd,&train.length,sizeof(train.length));
        recvn(netfd,train.data,train.length);
        memcpy(filename,train.data,train.length);
        printf("filename=%s\n",filename);

        // 收断点文件大小
        int size=0;
        recvn(netfd,&train.type,sizeof(train.type));
        recvn(netfd,&train.length,sizeof(train.length));
        recvn(netfd,train.data,train.length);
        memcpy(&size,train.data,train.length);
        printf("size=%d\n",size);

        // 算实际文件大小
        /* strcat(path,"/"); */
        /* strcat(path,filename); */
        struct stat statbuf;                                             
        /* stat(filename,&statbuf); */
        stat(path,&statbuf);
        int filesize=statbuf.st_size;
        printf("filesize=%d\n",filesize);
        train.type=0;
        train.length=sizeof(filesize);
        memcpy(train.data,&filesize,train.length);
        send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);
        send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
        send(netfd,train.data,train.length,MSG_NOSIGNAL);
 

        // 从断点处开始发文件
        int fd=open(path,O_RDWR);
        lseek(fd,size,SEEK_SET);
        if(filesize<10){
            while(1){
                bzero(train.data,sizeof(train.data));
                int ret=read(fd,train.data,sizeof(train.data));
                /* if(ret==0) break; */
                train.length=ret;
                train.type=0;
                send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);
                send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL); 
                send(netfd,train.data,train.length,MSG_NOSIGNAL);
                if(ret==0) break;
            }
        }else{
            printf("我是mmap\n");
            sendfile(netfd,fd,NULL,filesize-size);
            printf("发完了\n");
        }
        close(fd);
        return 0;
    }else if(train.type==22){
        // 执行正常逻辑
        // 收文件名
        char filename[1024]={0};
        recvn(netfd,&train.type,sizeof(train.type));
        recvn(netfd,&train.length,sizeof(train.length));
        recvn(netfd,train.data,train.length);
        memcpy(filename,train.data,train.length);
        printf("filename=%s\n",filename);

        // 算实际文件大小+发给对面
        /* strcat(path,"/"); */
        /* strcat(path,filename); */
        struct stat statbuf;
        /* stat(filename,&statbuf); */
        stat(path,&statbuf);
        printf("path=%s\n",path);
        int filesize=statbuf.st_size;
        printf("filesize=%d\n",filesize);
        train.type=0;
        train.length=sizeof(filesize);
        memcpy(train.data,&filesize,train.length);
        send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);
        send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
        send(netfd,train.data,train.length,MSG_NOSIGNAL);

        // 发文件
        int fd=open(path,O_RDWR);
        if(filesize<10){
            while(1){
                bzero(train.data,sizeof(train.data));
                int ret=read(fd,train.data,sizeof(train.data));
                /* if(ret==0) break; */
                train.length=ret;
                train.type=0;
                send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);
                send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL); 
                send(netfd,train.data,train.length,MSG_NOSIGNAL);
                if(ret==0) break;
            }
        }else{
            printf("我是mmap\n");
            sendfile(netfd,fd,NULL,filesize);
            printf("发完了\n");

        }
        close(fd);
        return 0;
    }
    return 0;
}

int s_recv_up(int netfd,commandStack_t *pcommandStack){
    print_stack(pcommandStack);
    char path[1024]={0};
    assemble_stack(pcommandStack,path);
    train_t train;
    // 收文件名
    recvn(netfd,&train.type,sizeof(train.type));
    recvn(netfd,&train.length,sizeof(train.length));
    recvn(netfd,train.data,train.length);
    char filename[1024]={0};
    memcpy(filename,train.data,train.length);
    printf("filename=%s\n",filename);
    strcat(path,"/");
    strcat(path,filename);
    int size=0;
    if(access(path,F_OK)==0){
        printf("断点续传\n");
        train.type=11;
        send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);

        // 发断点文件大小
        struct stat statbuf;
        printf("filename=%s\n",filename);
        stat(path,&statbuf);
        size=statbuf.st_size;
        printf("size=%d\n",size);
        train.type=0;
        train.length=sizeof(size);
        printf("train.lenght=%d\n",train.length);
        memcpy(train.data,&size,train.length);
        printf("train.data=%s\n",train.data);
        memcpy(train.data,&size,sizeof(size));
        send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);
        send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
        send(netfd,train.data,train.length,MSG_NOSIGNAL);

        // 收实际文件大小
        int filesize=0;
        recvn(netfd,&train.type,sizeof(train.type));
        recvn(netfd,&train.length,sizeof(train.length));
        recvn(netfd,train.data,train.length);
        memcpy(&filesize,train.data,train.length);
        printf("filesize=%d\n",filesize);

        
        // 收文件
        int fd=open(path,O_RDWR|O_CREAT|O_APPEND,0666);
        if(filesize<10){
            while(1){
                bzero(train.data,sizeof(train.data));
                /* if(train.length==0) break; */
                recvn(netfd,&train.type,sizeof(train.type));
                recvn(netfd,&train.length,sizeof(train.length));
                /* if(train.length==0) break; */
                recvn(netfd,train.data,train.length);
                if(train.length==0) break;
                write(fd,train.data,train.length);
            }
        }else{
            printf("我是mmap\n");
            ftruncate(fd,filesize);
            char *p=(char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
            recvn(netfd,p+size,filesize-size);
            /* write(fd,p,filesize-size); */
            munmap(p,filesize);
            printf("收完了\n");
        }
        return 0;
        
    }else{
        train.type=22;
        send(netfd,&train.type,sizeof(train.type),MSG_NOSIGNAL);

        // 收实际文件大小
        int filesize=0;
        recvn(netfd,&train.type,sizeof(train.type));
        recvn(netfd,&train.length,sizeof(train.length));
        recvn(netfd,train.data,train.length);
        memcpy(&filesize,train.data,train.length);
        printf("filesize=%d\n",filesize);


        // 正常收文件
        printf("正常收文件\n");
        int fd=open(path,O_RDWR|O_CREAT|O_TRUNC,0666);
        printf("path = %s\n", path);
        if(filesize<10){
            while(1){
                bzero(train.data,sizeof(train.data));
                /* if(train.length==0) break; */
                recvn(netfd,&train.type,sizeof(train.type));
                recvn(netfd,&train.length,sizeof(train.length));
                if(train.length==0) break;
                recvn(netfd,train.data,train.length);
                write(fd,train.data,train.length);
                printf("11111111111111111\n");
            }
        }else{
            printf("我是mmap\n");
            ftruncate(fd,filesize);
            char *p=(char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
            recvn(netfd,p,filesize);
            /* write(sockfd,p,filesize); */
            munmap(p,filesize);
            printf("收完了\n");

        }
        printf("3333333333333333\n");
    return 0;
    }
    return 0;
}


